package ru.sazonov.ide.parser.processor.java

import japa.parser.ast.visitor.VoidVisitorAdapter
import org.springframework.stereotype.Component
import japa.parser.ast.body.ClassOrInterfaceDeclaration
import japa.parser.ast.type.ClassOrInterfaceType
import japa.parser.ast.body.InitializerDeclaration
import japa.parser.ast.body.MethodDeclaration
import japa.parser.ast.PackageDeclaration
import japa.parser.ast.body.AnnotationDeclaration
import ru.sazonov.ide.model.ModelPart
import ru.sazonov.ide.model.java.Klass
import ru.sazonov.ide.model.java.JavaArtefactAdapter
import ru.sazonov.ide.model.java.Method
import ru.sazonov.ide.model.java.Type
import japa.parser.ast.body.Parameter
import japa.parser.ast.body.ConstructorDeclaration
import ru.sazonov.ide.model.java.Ctor

class BasicVisitorAdapter extends VoidVisitorAdapter {
    def String currentPackage;

    @Override
    void visit(ClassOrInterfaceDeclaration n, Object arg) {
        ModelPart mp = arg;
        mp.artefacts.add(new Klass(
                name: n.name,
                fullName: "${currentPackage}.${n.name}",
                doesExtends: n.extends.collect {
                    new Type(id: "${currentPackage}.${it.name}")
                },
                doesImplements: n.implements.collect {
                    new Type(id: "${currentPackage}.${it.name}")
                },
                methods: n.members.findAll{it instanceof MethodDeclaration}.collect{MethodDeclaration md ->
                    new Method(
                            name: md.name,
                            returnType: new Type(id:md.type),
                            args: md.parameters.collect {Parameter p ->
                                new Type(id: p.type);
                            }
                    )
                },
                ctors: n.members.findAll {it instanceof ConstructorDeclaration}.collect {ConstructorDeclaration cd ->
                    new Ctor(
                            args: cd.parameters.collect {Parameter p ->
                                new Type(id: p.type)
                            }
                    )
                }
        ).fix());
    }

    @Override
    void visit(PackageDeclaration n, Object arg) {
        currentPackage = n.name;
    }
}
